#include "CTextureOGL.h"
#include "CRendererOGL.h"

/// The OpenGL Texture Constructor
/**	@param w - width of texture in pixels
		@param h - height of texture in pixels
		@param data - a pointer to bytes of pixel data
		@param format - the format of the pixel data. It can be RGB, RGBA, X and many more
		@param flags - texture usage flags */
CTextureOGL::CTextureOGL( int w, int h, byte* data, int format, int flags )
		: 	ITexture( w, h, data, format, flags ) {

	if( flags == eDBF_DEFAULT_SETTINGS )
		flags = m_DefaultFlags;

	// If we want it in the VRAM (Video Adapter RAM)
	if( flags & eDBF_VRAM ) {
		// Generate texture name
		glGenTextures( 1, &m_uiOGLTextureID );

		#ifdef TZM_BUILD_SAFEMODE
			if( !m_uiOGLTextureID ) {
				m_bInvalid = true;
				return;
			}
		#endif

		// Enable our texture, so we can work with it
		glBindTexture( GL_TEXTURE_2D, m_uiOGLTextureID );

		// For now we set the texture environment as MODULATE. This means that vertex colors are multiplied by the texture, and this is the color output
		glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

		// When texture area is small, bilinear filter the closest mipmap
		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );

		// When texture area is large, bilinear filter the original
		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

		// The textures will wrap over at the edges (repeat)
		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

		// Build our texture with the data provided
		switch ( format ) {
			case eTF_RGBA32:
				gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, 	w, h, GL_RGBA, 	GL_UNSIGNED_BYTE, data );
				break;
			case eTF_RGB24:
				gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB,  	w, h, GL_RGB, 		GL_UNSIGNED_BYTE, data );
				break;
			case eTF_X8:
				gluBuild2DMipmaps( GL_TEXTURE_2D, GL_ALPHA, 	w, h, GL_ALPHA, 	GL_UNSIGNED_BYTE, data );
				break;
			default:
				gluBuild2DMipmaps( GL_TEXTURE_2D, GL_ALPHA,  w, h, GL_ALPHA, 	GL_UNSIGNED_BYTE, data );
				break;
		}

		// Disable this texture
		glBindTexture( GL_TEXTURE_2D, 0 );
	}

	// If we want it in the RAM
	if( flags & eDBF_RAM ) {
		m_RAMData = data;
	}

	#ifdef TZM_BUILD_SAFEMODE
		m_bInvalid = false;
	#endif
}

/// OpenGL Texture Destructor
CTextureOGL::~CTextureOGL( ) {
	glDeleteTextures( 1, &m_uiOGLTextureID );
}

/// Bind texture so we can use it
/**	@param stage - the stage to bind it to. @default is 0 */
void CTextureOGL::Bind( ui16 stage ) {
	// Set the active texture stage:
	glActiveTexture( GL_TEXTURE0 + stage );
	// And bind it:
	glBindTexture( GL_TEXTURE_2D, m_uiOGLTextureID );
}

